package version4.Server.serviceRegister.impl;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import version4.Server.serviceRegister.ServiceRegister;

import java.net.InetSocketAddress;

public class ZKServiceRegister implements ServiceRegister {
    private CuratorFramework client;
    private static final String ZK_ROOT_PATH = "MyRpc";
    // 白名单
    private static final String RETRY_ROOT_PATH="CanRetry";

    public ZKServiceRegister() {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        this.client = CuratorFrameworkFactory.builder().connectString("127.0.0.1:9090").
        sessionTimeoutMs(50000).namespace(ZK_ROOT_PATH).retryPolicy(retryPolicy).build();
        this.client.start();
        System.out.println("zookeeper 连接成功");
    }

    @Override
    public void register(String serviceName, InetSocketAddress address,boolean isRetry) {
        try{
            if(client.checkExists().forPath("/"+serviceName)==null){
                // 服务名称 创建为永久节点，服务下线仍然存在
                client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/"+serviceName);
            }
            // 服务地址 创建为临时节点，服务下线则自动删除
            client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).
                    forPath("/"+serviceName+"/"+getServiceAddress(address));
            if(isRetry){
                String path = "/"+RETRY_ROOT_PATH+"/"+serviceName;
                client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).
                        forPath(path);
            }

        } catch (Exception e) {
            System.out.println("服务已注册:"+serviceName+"->"+address);
        }
    }

    // String(ip:port) -> inetSocketAddress
    private InetSocketAddress parseAddress(String serviceAddress) {
        String[] split = serviceAddress.split(":");
        return new InetSocketAddress(split[0], Integer.parseInt(split[1]));
    }

    // inetSocketAddress -> String(ip:port)
    private String getServiceAddress(InetSocketAddress address) {
        return address.getHostString() + ":" + address.getPort();
    }
}
